#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <stdint.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <dlfcn.h>
#include <pthread.h>
#include <linux/fb.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <syslog.h>

int daemon_init(void)
{
	pid_t pid;
	int fd0, fd1, fd2, max_fd,i;	

	struct sigaction    sa;

	// 1: 忽略SIGHUP防止被控制终端杀死
	signal(SIGHUP, SIG_IGN);

	// 2: 退出原来父进程的进程组组长身份，以便可以正常执行setsid()
	if((pid = fork()) < 0)
	{
		perror("fork faild!");
		exit(1);
	}
	else if(pid != 0)
	{
		exit(0);
	}

	// 3: 新建一个会话，从而脱离原来会话及其控制终端的影响
	if(setsid() < 0)
	{
		exit(1);
	}

	// 4: 脱离原来子进程的会话创建者身份，防止再次打开终端文件
	if((pid = fork()) < 0)
	{
		perror("fork faild!");
		exit(1);
	}
	else if(pid != 0)
		exit(0);

	// 5: 新建并进入一个进程组，防止受到原进程组的影响
	setpgrp();

	// 6: 关闭并释放所有文件资源，因为文件会继承自父进程
	max_fd = sysconf(_SC_OPEN_MAX);
	for (i = max_fd; i>=0; i--)
	{
		close(i);
	}

	// 7: 将umask设置为0，防止其影响新建文件时所指定的权限
	umask(0);

	// 8: 将当前进程的所在路径更改为不可卸载的路径
	chdir("/");

	return 0;
}
